package orxatas.travelme.sync;

import java.util.ArrayList;
import java.util.List;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;

import android.content.ContentValues;
import android.content.Context;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;

import orxatas.travelme.activity.AsyncActivity;
import orxatas.travelme.databases.TravelmeDatabase;
import orxatas.travelme.entity.Comment;
import orxatas.travelme.entity.Group;
import orxatas.travelme.entity.User;
import orxatas.travelme.manager.AccountManager;
import orxatas.travelme.sync.SyncOptions.ParseAnswer;

/**
 * Sync account.
 * */
public class SyncAccount extends SyncOptions {
	
	/**
	 * The user logged.
	 * */
	static private User userLogged = null;
	
	/**
	 * The password from the user logged.
	 * */
	static private String password = null;
	
	static final private String lastUserLoggedDataID = "lastUserLoggedData"; 
	private SharedPreferences lastUserLoggedDataSP;
	private SharedPreferences.Editor lastUserLoggedDataED;
	static final private String lastUserLoggedData_iduser = "lastUserLoggedData_iduser";
	
	private AsyncActivity asyncActivity;
	
	/**
	 * Base de datos.
	 * */
	private SQLiteDatabase trvlmdb;
	private TravelmeDatabase databaseHelper;
	
	/**
	 * @param asyncActivity Activity to sync.
	 * */
	public SyncAccount(AsyncActivity asyncActivity){
		this.asyncActivity = asyncActivity;
		
		lastUserLoggedDataSP = asyncActivity.getActivity().getSharedPreferences(lastUserLoggedDataID, Context.MODE_PRIVATE);
		lastUserLoggedDataED = lastUserLoggedDataSP.edit();
		
		loadFromDB();
	}
	
	/**
	 * Check if there are a user logged already and tries to login.
	 * */
	private void loadFromDB(){
		int userLoggedID = lastUserLoggedDataSP.getInt(lastUserLoggedData_iduser, -1);
		if(userLoggedID == -1){
			disconnect();
			return;
		}
		
		databaseHelper = new TravelmeDatabase(asyncActivity.getActivity(), userLoggedID);
		
		//The user is logged already.
		if(userLogged != null) return;
		
		trvlmdb = databaseHelper.getReadableDatabase();
		Cursor answer = trvlmdb.rawQuery("SELECT * FROM "+TravelmeDatabase.USER_TNAME+" ;", null);
		
		int cid_email= answer.getColumnIndex(TravelmeDatabase.USER_CEMAIL);
		int cid_password = answer.getColumnIndex(TravelmeDatabase.USER_CPASSWORD);
		
		if(answer.moveToFirst()){
			userLogged = new User(userLoggedID, answer.getString(cid_email));
			password = answer.getString(cid_password);
		} else {
			Log.e("DATABASE", "Something wrong in DB data. User will not logged.");
			disconnect();
		}
		answer.close();
		trvlmdb.close();
	}
	
	private class AnswerUser extends Answer<User>{}
	
	/**
	 * Login a user into internet. Is a SYNC call.
	 * 
	 * @param email Email of user.
	 * @param password Password of user.
	 * 
	 * @return The user logged.
	 * */
	public User login(String email, String password){
		SyncInternetConnection newLoginCall = new SyncInternetConnection(TRVLMWS);
		
		List<NameValuePair> pairs = new ArrayList<NameValuePair>();
		pairs.add(new BasicNameValuePair("method", METHOD_AM+"."+ACTION_AM_LOGIN));
		pairs.add(new BasicNameValuePair("email", email));
		pairs.add(new BasicNameValuePair("pass", password));
		
		newLoginCall.addGETParams(pairs);
		String response = newLoginCall.send();
		
		try {
			AnswerUser answer = new ParseAnswer<AnswerUser>().parse(response, true, AnswerUser.class);
			if(answer.getState() == 0) userLogged = answer.getObj();
			SyncAccount.password = password;
			
			ContentValues v = new ContentValues();
			v.put(TravelmeDatabase.USER_CID, userLogged.getId());
			v.put(TravelmeDatabase.USER_CEMAIL, userLogged.getEmail());
			v.put(TravelmeDatabase.USER_CPASSWORD, password);
			v.put(TravelmeDatabase.USER_CNAME, userLogged.getUserName());
			v.put(TravelmeDatabase.USER_CLASTUPDATE, userLogged.getLastUpdate());
			
			if(databaseHelper != null){
				databaseHelper.close();
			}
			databaseHelper = new TravelmeDatabase(asyncActivity.getActivity(), userLogged.getId());
			
			lastUserLoggedDataED.putInt(lastUserLoggedData_iduser, userLogged.getId());
			lastUserLoggedDataED.commit();
			
			trvlmdb = databaseHelper.getWritableDatabase();
			trvlmdb.delete(TravelmeDatabase.USER_TNAME, TravelmeDatabase.USER_CID+" = "+userLogged.getId(), null);
			trvlmdb.insert(TravelmeDatabase.USER_TNAME, null, v);
			trvlmdb.close();
			
			return userLogged;
		} catch (WithoutObject e) {
			return null;
		}
	}
	
	private class AnswerUserReg extends Answer<User>{}
	/**
	 * Register a new user. Sync call.
	 * 
	 * @param email Email of the user.
	 * @param password Password of the user.
	 * */
	public boolean register(String email, String password, String name){
		SyncInternetConnection registerCall = new SyncInternetConnection(TRVLMWS);
		
		List<NameValuePair> pairs = new ArrayList<NameValuePair>();
		pairs.add(new BasicNameValuePair("method", METHOD_AM+"."+ACTION_AM_REGISTER));
		pairs.add(new BasicNameValuePair("email", email));
		pairs.add(new BasicNameValuePair("pass", password));
		pairs.add(new BasicNameValuePair("name", name));
		
		registerCall.addGETParams(pairs);
		String response = registerCall.send();
		
		Answer<User> answer;
		try {
			answer = new ParseAnswer<AnswerUserReg>().parse(response, true, AnswerUserReg.class);
			if(answer.getState() == 0) return true;
			else return false;
		} catch (WithoutObject e) {
			//There was any problem. Bad registration.
			return false;
		}
	}
	
	public User getUserLogged(){
		return userLogged;
	}
	
	/**
	 * Obtain the user password if the user is logged.
	 * */
	public String getPassword(){
		return password;
	}

	/**
	 * Disconnect a user.
	 * */
	public void disconnect(){
		userLogged = null;
		password = null;
		lastUserLoggedDataED.clear();
		lastUserLoggedDataED.commit();
	}
}
